Skip to content

feat(desktop): add password-protected backups in settings - #3701

Merged
tellaho merged 5 commits into
mainfrom
tho/nip49-settings-backup
Jul 30, 2026
Merged

feat(desktop): add password-protected backups in settings#3701
tellaho merged 5 commits into
mainfrom
tho/nip49-settings-backup

Conversation

@tellaho

@tellaho tellaho commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Category: new-feature
User Impact: Users can create, download, and verify a password-protected backup of their private identity from desktop Settings.

Problem: Buzz does not currently give signed-in users a Settings-based path to protect or validate their private identity independently of onboarding. Solution: Add a focused backup menu to the private-key row, keep encryption and verification local in Rust, and preserve completed encrypted backups briefly so native saves can be retried without repeating encryption.

File changes

desktop/src/features/settings/
Adds the background backup lifecycle, create and test dialogs, private-key menu integration, password handling, and focused unit coverage.

desktop/src/features/onboarding/ui/NsecMaskedDisplay.tsx
Extends the masked private-key display with reusable overflow-menu actions used by Settings.

desktop/src/app/App.tsx
Mounts the backup provider at app scope so encryption and save work survive closing Settings or the modal.

desktop/src/shared/api/tauriIdentity.ts
Adds typed desktop bindings for local backup creation, save, selection, and verification.

desktop/src-tauri/src/key_backup.rs and desktop/src-tauri/src/commands/identity.rs
Implements local NIP-49 encryption, password generation, file handling, and public-identity-only verification results.

desktop/src-tauri/src/egress_guard.rs and guarded call sites
Blocks encrypted secret material from relay, websocket, snapshot, sharing, and huddle egress paths.

desktop/src-tauri tests and fixtures
Covers encryption, verification, file behavior, and fail-closed no-egress protections.

desktop/src/testing/e2eBridge.ts, desktop/tests/, and desktop/playwright.config.ts
Expands the mock native bridge and browser coverage across create, retry, expiry, and current/different-identity verification states.

desktop/src-tauri/Cargo.toml, Cargo.lock, and assets
Adds the local cryptography/password-generation dependencies and embedded short-word list.

Reproduction steps

  1. Run the desktop app and open Settings → Profile → Identity.
  2. Open the private-key overflow menu and choose Create backup.
  3. Enter or generate a valid password, submit, and confirm progress continues if the dialog or Settings is closed.
  4. Save the resulting .ncryptsec file; cancel and retry to confirm the temporary download remains available.
  5. Choose Test backup, select the file, enter a wrong password, then retry with the correct password.
  6. Confirm success identifies whether the backup matches the current identity and displays only the public npub.

Screenshots

Settings identity Private-key menu Create backup
image image image
Encrypting Download available Test success
image image image

Visual review and additional states: Buzz thread

@tellaho
tellaho marked this pull request as ready for review July 30, 2026 14:59
@tellaho
tellaho requested a review from a team as a code owner July 30, 2026 14:59
npub1223z34hd7vtwc6qj4s7flsxkj644nlre2nthu7lrrmkumhu3xddsrx9r6w and others added 5 commits July 30, 2026 09:21
Co-authored-by: Taylor Ho <taylorkmho@gmail.com>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Preload NIP-49 encryption silently while preserving the editable password until submission.
- Replace queued-download status text with randomized progress and automatically open the native save dialog when encryption completes.
- Move the temporary backup workflow into a compact confirmation dialog with aligned guidance and actions.
- Preserve encrypted backups after canceled saves so the download dialog can be reopened without repeating encryption.
- Expand reducer and browser coverage for preload, retry, progress, modal lifecycle, and repeated downloads.

Co-authored-by: Taylor Ho <taylorkmho@gmail.com>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
- Add an app-level encrypted backup provider to preserve encryption and native save work after the modal or settings screen closes.
- Replace the standalone backup settings rows with private-key menu actions and a focused backup confirmation dialog.
- Preload NIP-49 encryption silently, show simulated progress after submission, and open the native save dialog automatically.
- Keep completed backups available for five minutes with a descending Download backup button and actionable Sonner status updates.
- Extend the masked private-key display with reusable overflow-menu actions for creating and testing backups.
- Update Playwright coverage for modal lifecycle, background completion, temporary downloads, expiry, and backup verification.

Co-authored-by: Taylor Ho <taylorkmho@gmail.com>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
@tellaho
tellaho force-pushed the tho/nip49-settings-backup branch from 23caa9f to 329f20e Compare July 30, 2026 16:40
@tellaho

tellaho commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

Resolved the blocking NIP-49 verification finding and rebased onto current main.

  • Untrusted backups now have their embedded log_n checked before EncryptedSecretKey::decrypt can invoke scrypt. Costs above 18 return an explicit unsupported-cost error.
  • Added boundary coverage proving log_n=18 remains accepted and log_n=19 is rejected before decryption.
  • Resolved the main integration overlap while retaining both the new linux_media wiring and backup/security modules.
  • Rebased head: 329f20e463a41f28a6ab3dfbe43ed0fb46c0d319.

Independent review confirmed the resource ceiling is on the only untrusted decrypt path and upstream-compatible backups at or below the ceiling still work. Full frontend/Rust suites and focused Settings/security tests passed locally; all PR checks are now green.

Two previously noted items remain non-blocking follow-ups: the stale BACKUP_FILE_NAME doc comment, and rust-nostr's normalized password/derived-key locals not currently using Zeroizing (upstream-library behavior).

@tellaho
tellaho merged commit bd0bff2 into main Jul 30, 2026
25 checks passed
@tellaho
tellaho deleted the tho/nip49-settings-backup branch July 30, 2026 18:15
wpfleger96 added a commit that referenced this pull request Jul 30, 2026
…chive

* origin/main:
  Fix video reviews in thread replies (#3719)
  feat(release): make desktop releases immutable (#3568)
  Make relay reconnect backoff authoritative (#3774)
  feat(desktop): add password-protected backups in settings (#3701)

Signed-off-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants